/*
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package io.iec.edp.caf.lockservice.api;

import lombok.Data;

import java.time.Duration;

/**
 *数据锁的设置选项，用以指定数据锁的附加行为。
 * @author wangyandong
 * @date 2019/7/27 13:38
 *
 */
@Data
public class DataLockOptions {

    /**
     * 数据锁选项的默认值。这是一个静态只读字段。
     * 通过该值获取到一个系统缺省提供的锁选项。其中，锁有效时间属性为“永久”，锁可被替换范围为“可被用户自己替换”，锁的作用域范围为“会话级”，锁的等待超时时间为“不等待”。
     * 相当于：<code>new DataLockOptions(TimeSpan.Zero, ReplaceScope.Self, TimeSpan.Zero); </code>
     */
    public static final DataLockOptions defaultOptions;

    static{
        defaultOptions = new DataLockOptions(Duration.ZERO, ReplacedScope.Session, LockedScope.Session, Duration.ZERO);
    }



    /// <summary>
    /// 获取或设置数据锁的持续时间，即从加锁之时开始，锁的有效时间跨度。
    /// </summary>
    /// <remarks>如果设置为<c>TimeSpan.Zero</c>，则指锁永久有效。如果没有设定，默认值为<c>TimeSpan.Zero</c>。</remarks>
    /// <example>
    /// 设置为永久：
    /// <c>LockOptions options = new LockOptions(TimeSpan.Zero);</c>
    /// 或者通过创建一个<see cref="System.TimeSpan"/>来设置持续时间，下面的例子是设置持续时间为1小时：
    /// <c>LockOptions options = new LockOptions(new TimeSpan(1, 0, 0););</c>
    /// </example>
    private Duration persistenceTime;

    /**
     * 获取或设置锁可被替换的范围，见<see cref="ReplacedScope"/>。
     * 通过设置锁可被替换范围，可指定当前锁在有效期内时，如果有其他请求（用户自己或其他用户）也希望对同样的数据进行锁定时，当前锁是否可被替换。
     * 如果没有设定，默认值为<c>ReplaceScope.Self</c>。
     */
    private ReplacedScope replacedScope;

    /**
     * 获取或设置锁的作用域范围。
     * 通过锁作用域范围的设置，可设置锁在那个作用域范围内有效。参见<see cref="LockedScope"/>。
     * 如果没有设定，默认值为<c>LockedScope.Session</c>。
     */
    private LockedScope lockedScope;

    /**
     * 获取或设置锁的等待超时时间，即当加锁时发生冲突（目前已经存在一个有效的锁）时，等待的时间。
     * 如果是对于单据类操作进行锁定，因为锁的持续时间往往较长，如果设置等待的超时时间，可能会导致用户界面长时间等待。
     * 对于锁定时间较短的操作是比较适合的，例如多人文档编辑操作。
     * 如果设置为<c>TimeSpan.Zero</c>，则表示当发生加锁冲突时，立即返回，加锁请求失败。
     */
    private Duration timeOut;

    /**
     *默认构造函数
     * @return 锁选项对象
     */
    public DataLockOptions()
    {
    }


    /**
     *根据输入的<b>持续时间</b>参数初始化数据锁选项对象。
     *@param persistenceTime 持续时间，用于指定锁的有效期限。
     * @return 锁选项对象
     */
    public DataLockOptions(Duration persistenceTime)
    {
        this(persistenceTime, ReplacedScope.Session);
    }

    /// <summary>
    ///
    /// </summary>
    /// <param name="scope"></param>
    /***
     *根据输入的<b>锁可被替换范围</b>参数初始化数据锁选项对象。
     * @param scope 锁可被替换范围，用于指定锁的可被替换的范围。
     * @return  锁选项对象
     */
    public DataLockOptions(ReplacedScope scope)
    {
        this(Duration.ZERO, scope);
    }

    /**
     *根据输入的<b>持续时间</b>和<b>锁可被替换范围</b>参数初始化数据锁选项对象。
     *
     * @param persistenceTime 持续时间，用于指定锁的有效期限。
     * @param replaceScope 锁可被替换范围，用于指定锁的可被替换的范围。
     * @return  锁选项对象
     */
    public DataLockOptions(Duration persistenceTime, ReplacedScope replaceScope)
    {
        this(persistenceTime, replaceScope, LockedScope.Session, Duration.ZERO);
    }

    /// <summary>
    /// 根据输入的<b>持续时间</b>、<b>锁可被替换的范围</b>、<b>锁的作用域</b>和<b>等待超时时间</b>参数初始化数据锁选项对象。
    /// </summary>
    /// <param name="persistenceTime">持续时间，用于指定锁的有效期限。</param>
    /// <param name="replaceScope">锁可被替换的范围，用于指定锁在那种情况下可以被替换。</param>
    /// <param name="lockedScope">锁的作用域范围，用于指定锁在哪个作用域内有效。</param>
    /// <param name="timeOut">等待超时时间，用于指定当发生锁冲突时的等待时间长短。</param>
    public DataLockOptions(Duration persistenceTime, ReplacedScope replaceScope, LockedScope lockedScope, Duration timeOut)
    {
        this.persistenceTime = persistenceTime;
        this.replacedScope = replaceScope;
        this.lockedScope = lockedScope;
        this.timeOut = timeOut;
    }
}
